package com.foreveross.proxyip.core.redis;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

/**
 * 工程内不准在其它类调用redis操作,只能在该类.
 * 
 * @author lyq
 * 
 * @param <T>
 */

public abstract class RedisExecutor<T> {
	int errorCount = 0;
	protected static final Logger log = Logger.getLogger(RedisExecutor.class);
	static Boolean isPass = false;
	// public JedisPool jedisPool = null;
	public Jedis jedis = null;
	public Transaction tran = null;
	//private static LatchControl mylatch = new LatchControl(10000L);

	// public RedisExecutor(JedisPool pool){
	// this.jedisPool = pool;
	// }

	// public RedisExecutor(){
	// this.jedisPool = RedisManager.getInstance().getJedisPool();
	// }

	public T exec() throws PiRedisExecption {
		try {
			//mylatch.waitLatch();
			jedis = RedisManager.getInstance().getJedisPool().getResource();
			return run();
		} catch (Exception e) {
			if (jedis != null) {
				RedisManager.getInstance().getJedisPool().returnBrokenResource(jedis);
			}
			
			/*if (tran != null) {
				tran.discard();
			}
			
			if (e instanceof JedisConnectionException) {
				errorCount++;
				log.info("new jedis pool :" + isPass);
				//isPass = false;
				synchronized (RedisExecutor.class) {
					if (!isPass) {
						try {
							// 唤醒锁让所有redis的执行的等待
							//mylatch.wakeupWait();
							RedisManager.getInstance().destoryPool();
							RedisManager.getInstance().getJedisPool();
							isPass = true;
							//mylatch.countDown();// 开锁,所有redis操作继续
							log.info("open lock~~~");
						} catch (Exception e1) {
							log.error(e1.getMessage(), e1);
							throw new RuntimeException(e);
						}
					}
					log.info("execute again!!!!!!!!!!");
				}
				log.info("----------------------redis exec error-----------------------------------");
				log.info(e);
				log.info("----------------------redis exec error-----------------------------------");
				// jedis = jedisPool.getResource();
				if (errorCount < 5) {
					try {
						RedisManager.getInstance().getJedisPool().returnResource(jedis);
					} catch (Exception e3) {
						log.error(e3.getMessage(), e3);
					}// 反正连接未断掉
					return exec();// 在新的jedispool下再跑一遍
				} else {
					log.error(e.getMessage(), e);
					throw new PiRedisExecption(e);
				}

			}
			return null;
			// throw new PiRedisExecption(e);*/
			return null;
		} finally {
			if (jedis != null) {
				RedisManager.getInstance().getJedisPool().returnResource(jedis);
			}
		}
	}

	public abstract T run() throws Exception;

}
